package cvo.chess.client.ui.chessboard;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.HasMouseOutHandlers;
import com.google.gwt.event.dom.client.HasMouseOverHandlers;
import com.google.gwt.event.dom.client.HasMouseUpHandlers;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

import cvo.chess.client.entities.IGameFacade;
import cvo.chess.client.entities.chessboard.ITile;
import cvo.chess.client.entities.game.IPiece;

public class TileWidget extends Composite implements HasMouseOverHandlers,
		HasMouseOutHandlers, HasMouseUpHandlers {

	private static TileWidgetUiBinder uiBinder = GWT
			.create(TileWidgetUiBinder.class);

	interface TileWidgetUiBinder extends UiBinder<Widget, TileWidget> {
	}

	// See:
	// https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder#Hello_Stylish_World
	interface TileStyle extends CssResource {
		String white();

		String black();

		String enlightened();

		String strongBorder();

		String noBorder();
		
		String possibleMovePosition();
	}

	IGameFacade gf;

	private String a1notation;

	// The tile should not change during a game
	// Therefore we keep track of the object instead using
	// gf.getTileAt("A1-notation"); every time
	private ITile tile;
	private PieceWidget piece;

	@UiField
	TileStyle style;
	@UiField
	Label position;
	@UiField
	HTMLPanel zonePanel;

	// TODO: use a PieceWidget instead of a simple Label
	@UiField
	Image pieceWidget;

	public TileWidget() {
		initWidget(uiBinder.createAndBindUi(this));
		getElement().addClassName(style.noBorder());
	}

	public TileWidget(IGameFacade gf, String a1notation) {
		this();
		this.gf = gf;
		this.a1notation = a1notation;
		this.tile = gf.getTileAt(a1notation);
		drawColor();
		drawPiece();
	}
	
	public String getA1Notation(){
		return this.a1notation;
	}

	public void drawColor() {
//		this.position.setText(this.tile.getPosition());
		
		
		if (tile.getColor().equals("WHITE")) {
			getElement().removeClassName(style.black());
			getElement().addClassName(style.white());
		} else {
			getElement().removeClassName(style.white());
			getElement().addClassName(style.black());
		}
	}

	public void drawPiece() {
		IPiece p = gf.getPieceAt(this.a1notation);
		
		if (p != null) {
			this.piece = new PieceWidget(p.toString());
			//this.pieceWidget = this.piece.getPieceWidget();
			this.pieceWidget.setUrl(this.piece.getPieceWidget());
//			return this.piece.getPieceWidget();
			
			
			//this.zonePanel.add(this.piece.getPieceWidget());
			
		} else {
			this.piece = new PieceWidget("-");
//			return this.piece.getPieceWidget();
			//this.zonePanel.add(this.piece.getPieceWidget());
			this.pieceWidget.setUrl(this.piece.getPieceWidget());
		}
	}

	public void update() {
		drawPiece();
	}

	public void lightUp(boolean on) {
		if (on) {
			getElement().addClassName(style.enlightened());
		} else {
			getElement().removeClassName(style.enlightened());
		}
	}

	public void hardBorder(boolean on) {
		if (on) {
			getElement().addClassName(style.strongBorder());
			getElement().removeClassName(style.noBorder());
		} else {
			getElement().addClassName(style.noBorder());
			getElement().removeClassName(style.strongBorder());
		}
	}
	
	public void isPossibleMovePosition(boolean on) {
		if (on) {
			getElement().addClassName(style.possibleMovePosition());
			getElement().removeClassName(style.noBorder());
		} else {
			getElement().addClassName(style.noBorder());
			getElement().removeClassName(style.possibleMovePosition());
		}
	}

	@Override
	public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
		return addDomHandler(handler, MouseOverEvent.getType());
	}

	@Override
	public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
		return addDomHandler(handler, MouseOutEvent.getType());
	}

	@Override
	public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
		return addDomHandler(handler, MouseUpEvent.getType());
	}
}
